<?php

namespace chick1993\util;

class Time
{
    const TYPE_STAMP = 1;
    const TYPE_DATE  = 2;

    /**
     * 取上个月最后一天
     * @param $time
     * @param int|string $type
     * @param string $format
     * @return false|mixed|string
     */
    static public function getLastMonthEndDay($time, $type = self::TYPE_DATE, string $format = 'Y-m-d')
    {
        $monthFirstDay = self::getMonthFirstDay($time, $type, $format);
        $stamp = strtotime($monthFirstDay . '-1 day');
        return self::getReturnType($stamp, $type, $format);
    }

    /**
     * 取上月1号日期
     * @param $time
     * @param string|int $type --返回类型，可选 Time::TYPE_DATE,Time::TYPE_STAMP 或者 时间格式字符串
     * @param string $format 时间格式字符串
     * @return false|int|string
     */
    static public function getLastMonthFirstDay($time, $type = self::TYPE_DATE, string $format = 'Y-m-d')
    {
        $monthFirstDay = self::getMonthFirstDay($time, $type, $format);
        $stamp = strtotime($monthFirstDay . '-1 month');
        return self::getReturnType($stamp, $type, $format);
    }

    /**
     * 取上个月今天
     * @param $time
     * @param string|int $type --返回类型，可选 Time::TYPE_DATE,Time::TYPE_STAMP 或者 时间格式字符串
     * @param string $format 时间格式字符串
     * @return false|int|string
     */
    static public function getLastMonthToday($time, $type = self::TYPE_DATE, string $format = 'Y-m-d')
    {
        $stamp = self::toStamp($time);
        $date = date('Y-m-d H:i:s', $stamp);
        $stamp = strtotime($date . '-1 month');
        return self::getReturnType($stamp, $type, $format);
    }

    /**
     * 取去年今天
     * @param $time
     * @param string|int $type --返回类型，可选 Time::TYPE_DATE,Time::TYPE_STAMP 或者 时间格式字符串
     * @param string $format 时间格式字符串
     * @return false|int|string
     */
    static public function getLastYearToday($time, $type = self::TYPE_DATE, string $format = 'Y-m-d')
    {
        $stamp = self::toStamp($time);
        $date = date('Y-m-d H:i:s', $stamp);
        $stamp = strtotime($date . '-1 year');
        return self::getReturnType($stamp, $type, $format);
    }

    /**
     * 取当前月最后一天
     * @param $time
     * @param string|int $type --返回类型，可选 Time::TYPE_DATE,Time::TYPE_STAMP 或者 时间格式字符串
     * @param string $format 时间格式字符串
     * @return false|int|string
     */
    static public function getMonthEndDay($time, $type = self::TYPE_DATE, string $format = 'Y-m-d')
    {
        $day = self::getMonthFirstDay($time);
        $date = date('Y-m-d 23:59:59', strtotime($day . ' +1 month -1 second'));
        $stamp = strtotime($date);
        return self::getReturnType($stamp, $type, $format);
    }

    /**
     * @param $time
     * @param string|int $type --返回类型，可选 Time::TYPE_DATE,Time::TYPE_STAMP 或者 时间格式字符串
     * @param string $format 时间格式字符串
     * @return false|int|string
     */
    static public function getMonthFirstDay($time, $type = self::TYPE_DATE, string $format = 'Y-m-d')
    {
        $stamp = self::toStamp($time);
        $date = date('Y-m-01 00:00:00', $stamp);
        $stamp = strtotime($date);
        if (!is_integer($type)) {
            $format = $type;
            $type = self::TYPE_DATE;
        }
        switch ($type) {
            case self::TYPE_DATE:
                return date($format, $stamp);
            default:
                return $stamp;
        }
    }

    /**
     * 格式化一个本地时间／日期
     * @param $time
     * @param string $format
     * @return false|string
     */
    static public function toDate($time, string $format = 'Y-m-d H:i:s')
    {
        $time = self::toStamp($time);
        return date($format, $time);
    }

    /**
     * 字符串转范围时间
     * @param $time
     * @param string $format
     * @param string $separator
     * @return array
     */
    static public function toRangeDate($time, string $format = 'Y-m-d H:i:s', string $separator = ','): array
    {
        $time = self::toRangeStamp($time, $separator);
        foreach ($time as $k => $t) {
            if (!empty($t)) {
                $time[$k] = date($format, $t);
            } else {
                $time = [];
                break;
            }
        }
        return $time;
    }

    /**
     * 字符串转范围时间戳
     * @param $time
     * @param string $separator
     * @return array
     */
    static public function toRangeStamp($time, string $separator = ','): array
    {
        if (!is_array($time)) $time = explode($separator, $time);
        if (count($time) != 2) return [];
        foreach ($time as $k => $v) $time[$k] = self::toStamp($v);
        return $time;
    }

    /**
     * 将任何字符串的日期时间描述解析为 Unix 时间戳
     * @param $val
     * @return false|int
     */
    static public function toStamp($val)
    {
        if (!is_numeric($val) && !is_string($val)) return 0;
        if (!is_numeric($val)) $val = strtotime($val);
        return $val;
    }

    static private function getReturnType($stamp, $type, $format)
    {
        if (!is_integer($type)) {
            $format = $type;
            $type = self::TYPE_DATE;
        }
        switch ($type) {
            case self::TYPE_DATE:
                return date($format, $stamp);
            default:
                return $stamp;
        }
    }
}
